package main.java.FSMDE.persistence;

import java.util.ArrayList;
import java.util.UUID;

import main.java.ERMDE.models.Attribute;
import main.java.ERMDE.models.Entity;
import main.java.FSMDE.models.ComplexComponent;
import main.java.FSMDE.models.Component;
import main.java.FSMDE.models.ComponentCollection;
import main.java.FSMDE.models.Diagram;
import main.java.FSMDE.models.ErmFsmRelationSet;
import main.java.FSMDE.models.Interface;
import main.java.FSMDE.models.RelatedComponent;

import org.w3c.dom.Element;


public class ErmFsmRelationXmlManager {

	public void generateRelations(Diagram diagram, Element interfacesElements,
			ArrayList<main.java.ERMDE.models.Diagram> ermDiagrams) {

		ArrayList<RelatedComponent> relatedComponents = getRelatedComponentsFromDiagram(diagram);

		for (RelatedComponent relatedComponent : relatedComponents) {
			Element relatedComponentElement = getElementOf(relatedComponent,
					interfacesElements);

			Element ermFsrRelations = (Element) (relatedComponentElement
					.getElementsByTagName("fsmErmRelations").item(0));

			for (int i = 0; i < ermFsrRelations
					.getElementsByTagName("relation").getLength(); i++) {
				Element relationElement = (Element) (ermFsrRelations
						.getElementsByTagName("relation").item(i));
				generateRelation(relatedComponent, relationElement, ermDiagrams);
			}
		}
	}

	private void generateRelation(RelatedComponent relatedComponent,
			Element relationElement, ArrayList<main.java.ERMDE.models.Diagram> ermDiagrams) {

		main.java.ERMDE.models.Diagram diagramRelated = null;
		for (main.java.ERMDE.models.Diagram diagram : ermDiagrams) {
			if (diagram.getId().toString()
					.equals(relationElement.getAttribute("ermDiagramId"))) {
				diagramRelated = diagram;
				break;
			}
		}
		if (diagramRelated != null) {
			Entity entityRelated = diagramRelated.getEntities().get(
					UUID.fromString(relationElement.getAttribute("entityId")));
			if (entityRelated != null) {
				Attribute attributeRelated = entityRelated.getAttributes().get(
						relationElement.getAttribute("attributeId"));
				if (attributeRelated != null) {
					Component textFieldRelated = ((RelatedComponent) relatedComponent)
							.getComponents().get(
									UUID.fromString(relationElement
											.getAttribute("componentId")));
					((RelatedComponent) relatedComponent).getComponents()
							.remove(textFieldRelated);
					Component newTextField;
					try {
						newTextField = ((RelatedComponent) relatedComponent)
								.setRelationToErmAttribute(diagramRelated,
										entityRelated, attributeRelated);
						newTextField.setId(UUID.fromString(relationElement
								.getAttribute("componentId")));
						ErmFsmRelationSet relationSet = ((RelatedComponent) relatedComponent)
								.getRelatedErmModel(newTextField);
						newTextField.showRelationWithErmDiagram(relationSet);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		}
	}

	private Element getElementOf(RelatedComponent relatedComponent,
			Element interfacesElements) {

		for (int i = 0; i < interfacesElements
				.getElementsByTagName("component").getLength(); i++) {
			Element componentElement = (Element) (interfacesElements
					.getElementsByTagName("component").item(i));
			if (relatedComponent.getId().toString()
					.equals(componentElement.getAttribute("id"))) {
				return componentElement;
			}
		}
		return null;
	}

	private ArrayList<RelatedComponent> getRelatedComponentsFromDiagram(
			Diagram diagram) {

		ArrayList<RelatedComponent> list = new ArrayList<RelatedComponent>();
		for (Interface interface0 : diagram.getInterfaces()) {
			list.addAll(getRelatedComponentsFrom(interface0.getComponents()));
		}
		return list;
	}

	private ArrayList<RelatedComponent> getRelatedComponentsFrom(
			ComponentCollection components) {
		ArrayList<RelatedComponent> list = new ArrayList<RelatedComponent>();
		for (Component component : components) {
			if (component instanceof ComplexComponent) {
				list.addAll(getRelatedComponentsFrom(((ComplexComponent) component)
						.getComponents()));
			}
			if (component instanceof RelatedComponent) {
				list.add((RelatedComponent) component);
			}
		}
		return list;
	}

}
